package fr.alma.music;


import static fr.alma.domo.music.PositionService.POSITION_BATHROOM;
import static fr.alma.domo.music.PositionService.POSITION_KITCHEN;
import static fr.alma.domo.music.PositionService.POSITION_LIVING_ROOM;
import static fr.alma.domo.music.PositionService.POSITION_WC;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import org.apache.tuscany.sca.node.Contribution;
import org.apache.tuscany.sca.node.ContributionLocationHelper;
import org.apache.tuscany.sca.node.Node;
import org.apache.tuscany.sca.node.NodeFactory;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

import fr.alma.domo.music.MusicService;
import fr.alma.domo.music.PositionControlService;
import fr.alma.domo.music.PositionService;
import fr.alma.domo.music.rc.HP;
import fr.alma.domo.music.rc.Player;
import fr.alma.domo.svc.AdaptationHandler;
import fr.alma.domo.svc.ContextHandler;
import fr.alma.domo.svc.SelectionAndDiscoveryImpl;
import fr.alma.domo.util.Log;

@SuppressWarnings("unused")
public class Scenario1{	
	private static Node node;	
	private static MusicService musicService;
	private static PositionService positionService;
	private static ContextHandler contextHandler;
	private static AdaptationHandler adaptationHandler;
	private static PositionControlService positionControlService;;
	private static Thread adaptationThread,positionControlServiceThread;
	
	private String clientId;
	private Player player1,player2;
	private HP hpBathroom,hpKitchen,hpLivingRoom,hpWC;
	
	@Before
	public void setUp() throws Exception {
		//on cree un client
		clientId = positionService.getClientId("James Deano");
		
		//On cree des lecteurs
		player1 = new Player();
		player1.startService();
		
		player2 = new Player();
		player2.startService();
		
		//On cree des hauts parleurs
		hpBathroom=new HP(POSITION_BATHROOM);
		hpBathroom.startService();

		hpKitchen=new HP(POSITION_KITCHEN);
		hpKitchen.startService();
		
		hpLivingRoom=new HP(POSITION_LIVING_ROOM);
		hpLivingRoom.startService();

		hpWC=new HP(POSITION_WC);
		hpWC.startService();
	}

	@After
	public void tearDown() throws Exception {
		player1.stopService();
		player2.stopService();
		hpBathroom.stopService();
		hpLivingRoom.stopService();
		hpWC.stopService();
		hpKitchen.stopService();
		clientId=null;
		player1=player2=null;
		hpBathroom=hpKitchen=hpLivingRoom=hpWC=null;
	}

	@BeforeClass
	public static void setUpBeforeClass() throws Throwable{		
		String location1 = ContributionLocationHelper.getContributionLocation(MusicService.class);
		String location2 = ContributionLocationHelper.getContributionLocation(SelectionAndDiscoveryImpl.class);

		if(node==null){
			//on charge le composite musique
			node = NodeFactory.newInstance().createNode(
					new Contribution("c1", location1)
					,new Contribution("c2",location2));
			node.start();
		}

		//Recuperation du service de musique		
		musicService = node.getService(MusicService.class, "MusicServiceComponent");

		//Recuperation et demarrage du service de position
		positionService = node.getService(PositionService.class, "PositionServiceComponent");

		//On demarre le service de control de position
		positionControlService = node.getService(PositionControlService.class, "PositionControlServiceComponent");
		positionControlServiceThread = new Thread(new Runnable(){

			@Override
			public void run() {
				positionControlService.startPositionControlLoop();
			}});
		positionControlServiceThread.setDaemon(true);
		positionControlServiceThread.start();
		
		//Recuperation du context handler
		contextHandler = node.getService(ContextHandler.class, "ContextHandlerComponent");
		
		//Recuperation et demarrage du gestionnaire d' adaptation
		adaptationHandler = node.getService(AdaptationHandler.class,"AdaptationHandlerComponent");
		adaptationThread = new Thread(new Runnable(){

			@Override
			public void run() {
				adaptationHandler.startAdaptationLoop();
			}
			
		});
		adaptationThread.setDaemon(true);
		adaptationThread.start();
	}
	
	@AfterClass
	public static void tearDownAfterClass() throws Throwable{
		if(node!=null){
			node.stop();
		}
		node=null;
		musicService=null;
		positionService=null;
		contextHandler=null;
		adaptationThread=null;
		positionControlServiceThread=null;
	}
	
	/**
	 * Test d'une lecture simple avec un lecteur et une chanson
	 */
	@Test
	public void testPlaySong(){
		Log.i(getClass().getName(), "================ TEST PLAY SONG");
		//on enregisitre une chanson
		String song = "A great song";
		player1.addSong(song);
		//on poisitionne le client dans la cuisine
		positionService.setClientPosition(clientId, POSITION_KITCHEN);		
		//on lit le titre voulut
		musicService.playSong(clientId, song);
		//on verifie que le son est bien diffusé dans la cuisine
		assertTrue(hpKitchen.isBusy());
		Log.i(getClass().getName(), "*****************************************");
		Log.i(getClass().getName(), "");
	}
	
}
